#include "fileinforepository.h"
#include <QDebug>
#include <QDateTime>
#include <algorithm>
FileInfoRepository::FileInfoRepository(QObject* parent)
    : QObject(parent)
    , m_nextTimestamp(QDateTime::currentMSecsSinceEpoch())
    , m_nextOriginalOrder(0)
{
}
// === 核心数据操作 ===
void FileInfoRepository::addFile(const UnifiedFileInfo& fileInfo)
{
    if (!fileInfo.isValid()) {
        return;
    }
    // 检查是否已存在
    FileListIndex existingIndex = findFileByIdentity(fileInfo.fileIdentity);
    if (existingIndex.isValid()) {
        updateFile(existingIndex, fileInfo);
        return;
    }
    // 创建新条目
    FileEntry entry(fileInfo);
    entry.originalOrder = m_nextOriginalOrder++;
    // 添加到列表
    int newIndex = m_files.size();
    m_files.append(entry);
    // 更新映射
    m_nameToIndex[fileInfo.fileName] = FileListIndex(newIndex);
    m_idToIndex[fileInfo.fileIdentity] = FileListIndex(newIndex);
    m_pathToIndex[fileInfo.filePath] = FileListIndex(newIndex);
    emit fileAdded(FileListIndex(newIndex), fileInfo);
}
void FileInfoRepository::removeFile(const FileListIndex& index)
{
    if (!isValidIndex(index)) {
        return;
    }
    int listIndex = index.value();
    const UnifiedFileInfo& fileInfo = m_files[listIndex].info;
    // 从映射中移除
    m_nameToIndex.remove(fileInfo.fileName);
    m_idToIndex.remove(fileInfo.fileIdentity);
    m_pathToIndex.remove(fileInfo.filePath);
    // 从列表中移除
    m_files.removeAt(listIndex);
    // 更新后续索引的映射
    for (int i = listIndex; i < m_files.size(); ++i) {
        const UnifiedFileInfo& info = m_files[i].info;
        m_nameToIndex[info.fileName] = FileListIndex(i);
        m_idToIndex[info.fileIdentity] = FileListIndex(i);
        m_pathToIndex[info.filePath] = FileListIndex(i);
    }
    emit fileRemoved(index, fileInfo);
}
void FileInfoRepository::updateFile(const FileListIndex& index, const UnifiedFileInfo& fileInfo)
{
    if (!isValidIndex(index)) {
        return;
    }
    int listIndex = index.value();
    const UnifiedFileInfo& oldInfo = m_files[listIndex].info;
    // 更新文件信息
    updateFileEntry(listIndex, fileInfo);
    emit fileUpdated(index, fileInfo);
}
void FileInfoRepository::moveFiles(const FileListIndexRange& fromIndices, const FileListIndex& toIndex)
{
    if (fromIndices.isEmpty()) {
        return;
    }
    // 验证所有索引
    for (const FileListIndex& index : fromIndices) {
        if (!isValidIndex(index)) {
            return;
        }
    }
    if (!toIndex.isValid() && toIndex.value() > m_files.size()) {
        return;
    }
    // 收集要移动的条目
    QList<FileEntry> entriesToMove;
    for (const FileListIndex& index : fromIndices) {
        entriesToMove.append(m_files[index.value()]);
    }
    // 从原位置移除（从后往前移除以避免索引变化）
    QList<int> sortedIndices;
    for (const FileListIndex& index : fromIndices) {
        sortedIndices.append(index.value());
    }
    std::sort(sortedIndices.begin(), sortedIndices.end(), std::greater<int>());
    for (int listIndex : sortedIndices) {
        m_files.removeAt(listIndex);
    }
    // 计算新的插入位置
    int insertIndex = toIndex.isValid() ? toIndex.value() : m_files.size();
    insertIndex = qBound(0, insertIndex, m_files.size());
    // 在目标位置插入
    for (int i = 0; i < entriesToMove.size(); ++i) {
        m_files.insert(insertIndex + i, entriesToMove[i]);
    }
    // 重建映射
    rebuildMappings();
    // 发出重排序信号
    QList<UnifiedFileInfo> newOrder;
    for (const FileEntry& entry : m_files) {
        newOrder.append(entry.info);
    }
    emit filesReordered(newOrder);
}
void FileInfoRepository::clearAll()
{
    m_files.clear();
    m_nameToIndex.clear();
    m_idToIndex.clear();
    m_pathToIndex.clear();
    m_nextOriginalOrder = 0;
    emit repositoryCleared();
}
// === 查询接口 ===
UnifiedFileInfo FileInfoRepository::getFile(const FileListIndex& index) const
{
    if (!isValidIndex(index)) {
        return UnifiedFileInfo();
    }
    return m_files[index.value()].info;
}
QList<UnifiedFileInfo> FileInfoRepository::getAllFiles() const
{
    QList<UnifiedFileInfo> files;
    for (const FileEntry& entry : m_files) {
        files.append(entry.info);
    }
    return files;
}
FileListIndex FileInfoRepository::getFileCount() const
{
    return FileListIndex(m_files.size());
}
FileListIndex FileInfoRepository::findFileByName(const QString& fileName) const
{
    auto it = m_nameToIndex.find(fileName);
    if (it != m_nameToIndex.end()) {
        return it.value();
    }
    return FileListIndex(-1);
}
FileListIndex FileInfoRepository::findFileByIdentity(const QString& fileIdentity) const
{
    auto it = m_idToIndex.find(fileIdentity);
    if (it != m_idToIndex.end()) {
        return it.value();
    }
    return FileListIndex(-1);
}
QList<FileListIndex> FileInfoRepository::findFilesByNames(const QStringList& fileNames) const
{
    QList<FileListIndex> indices;
    for (const QString& fileName : fileNames) {
        FileListIndex index = findFileByName(fileName);
        if (index.isValid()) {
            indices.append(index);
        }
    }
    return indices;
}
FileListIndex FileInfoRepository::findFileByPath(const QString& filePath) const
{
    auto it = m_pathToIndex.find(filePath);
    if (it != m_pathToIndex.end()) {
        return it.value();
    }
    return FileListIndex(-1);
}
QList<FileListIndex> FileInfoRepository::findFilesByStatus(FileStatusIconManager::FileStatus status) const
{
    QList<FileListIndex> indices;
    for (int i = 0; i < m_files.size(); ++i) {
        if (m_files[i].info.status == status) {
            indices.append(FileListIndex(i));
        }
    }
    return indices;
}
QList<FileListIndex> FileInfoRepository::findFilesByProcessStatus(FileProcessStatus status) const
{
    QList<FileListIndex> indices;
    for (int i = 0; i < m_files.size(); ++i) {
        if (m_files[i].info.processStatus == status) {
            indices.append(FileListIndex(i));
        }
    }
    return indices;
}
// === 批量操作 ===
void FileInfoRepository::addFiles(const QList<UnifiedFileInfo>& fileInfos)
{
    for (const UnifiedFileInfo& fileInfo : fileInfos) {
        addFile(fileInfo);
    }
}
void FileInfoRepository::removeFiles(const QList<FileListIndex>& indices)
{
    // 从后往前移除以避免索引变化
    QList<int> sortedIndices;
    for (const FileListIndex& index : indices) {
        if (isValidIndex(index)) {
            sortedIndices.append(index.value());
        }
    }
    std::sort(sortedIndices.begin(), sortedIndices.end(), std::greater<int>());
    for (int listIndex : sortedIndices) {
        removeFile(FileListIndex(listIndex));
    }
}
void FileInfoRepository::updateFiles(const QList<QPair<FileListIndex, UnifiedFileInfo>>& updates)
{
    for (const auto& update : updates) {
        updateFile(update.first, update.second);
    }
}
// === 状态管理 ===
void FileInfoRepository::setFileStatus(const FileListIndex& index, FileStatusIconManager::FileStatus status)
{
    if (!isValidIndex(index)) {
        return;
    }
    int listIndex = index.value();
    m_files[listIndex].info.status = status;
    emitFileUpdated(listIndex);
    emit fileStatusChanged(index, status);
}
void FileInfoRepository::setFileProcessStatus(const FileListIndex& index, FileProcessStatus status)
{
    if (!isValidIndex(index)) {
        return;
    }
    int listIndex = index.value();
    m_files[listIndex].info.processStatus = status;
    emitFileUpdated(listIndex);
}
void FileInfoRepository::updateFileProgress(const FileListIndex& index, int progress, const QString& statusText)
{
    if (!isValidIndex(index)) {
        return;
    }
    int listIndex = index.value();
    m_files[listIndex].info.updateProgress(progress, statusText);
    emitFileUpdated(listIndex);
    emit fileProgressUpdated(index, progress, statusText);
}
void FileInfoRepository::setFileError(const FileListIndex& index, const QString& errorMessage)
{
    if (!isValidIndex(index)) {
        return;
    }
    int listIndex = index.value();
    m_files[listIndex].info.setError(errorMessage);
    emitFileUpdated(listIndex);
}
void FileInfoRepository::setFileCompleted(const FileListIndex& index)
{
    if (!isValidIndex(index)) {
        return;
    }
    int listIndex = index.value();
    m_files[listIndex].info.setCompleted();
    emitFileUpdated(listIndex);
}
// === 验证和调试 ===
bool FileInfoRepository::isValidIndex(const FileListIndex& index) const
{
    return index.isValid() && index.value() >= 0 && index.value() < m_files.size();
}
QString FileInfoRepository::getRepositoryState() const
{
    return QString("FileInfoRepository State:\n"
                   "  Total files: %1\n"
                   "  Name mappings: %2\n"
                   "  ID mappings: %3\n"
                   "  Path mappings: %4\n"
                   "  Next timestamp: %5\n"
                   "  Next order: %6")
        .arg(m_files.size())
        .arg(m_nameToIndex.size())
        .arg(m_idToIndex.size())
        .arg(m_pathToIndex.size())
        .arg(m_nextTimestamp)
        .arg(m_nextOriginalOrder);
}
bool FileInfoRepository::verifyIntegrity() const
{
    // 检查列表大小与映射一致性
    if (m_nameToIndex.size() != m_files.size() ||
        m_idToIndex.size() != m_files.size() ||
        m_pathToIndex.size() != m_files.size()) {
        return false;
    }
    // 检查映射正确性
    for (int i = 0; i < m_files.size(); ++i) {
        const UnifiedFileInfo& info = m_files[i].info;
        if (m_nameToIndex[info.fileName].value() != i ||
            m_idToIndex[info.fileIdentity].value() != i ||
            m_pathToIndex[info.filePath].value() != i) {
            return false;
        }
    }
    return true;
}
// === 统计信息 ===
int FileInfoRepository::getTotalPageCount() const
{
    int total = 0;
    for (const FileEntry& entry : m_files) {
        total += entry.info.calculateTotalPages();
    }
    return total;
}
qint64 FileInfoRepository::getTotalFileSize() const
{
    qint64 total = 0;
    for (const FileEntry& entry : m_files) {
        total += entry.info.fileSize;
    }
    return total;
}
int FileInfoRepository::getFileCountByType(FileType type) const
{
    int count = 0;
    for (const FileEntry& entry : m_files) {
        if (entry.info.fileType == type) {
            count++;
        }
    }
    return count;
}
int FileInfoRepository::getProcessedFileCount() const
{
    int count = 0;
    for (const FileEntry& entry : m_files) {
        if (entry.info.isProcessingComplete()) {
            count++;
        }
    }
    return count;
}
int FileInfoRepository::getErrorFileCount() const
{
    int count = 0;
    for (const FileEntry& entry : m_files) {
        if (entry.info.hasError()) {
            count++;
        }
    }
    return count;
}
// === 导入导出 ===
QList<UnifiedFileInfo> FileInfoRepository::exportFiles(const QList<FileListIndex>& indices) const
{
    QList<UnifiedFileInfo> files;
    for (const FileListIndex& index : indices) {
        if (isValidIndex(index)) {
            files.append(getFile(index));
        }
    }
    return files;
}
void FileInfoRepository::importFiles(const QList<UnifiedFileInfo>& files, const FileListIndex& insertIndex)
{
    int startIndex = insertIndex.isValid() ? insertIndex.value() : m_files.size();
    for (int i = 0; i < files.size(); ++i) {
        const UnifiedFileInfo& fileInfo = files[i];
        // 检查是否已存在
        FileListIndex existingIndex = findFileByIdentity(fileInfo.fileIdentity);
        if (existingIndex.isValid()) {
            continue;
        }
        // 创建新条目
        FileEntry entry(fileInfo);
        entry.originalOrder = m_nextOriginalOrder++;
        // 插入到指定位置
        m_files.insert(startIndex + i, entry);
        // 更新映射
        m_nameToIndex[fileInfo.fileName] = FileListIndex(startIndex + i);
        m_idToIndex[fileInfo.fileIdentity] = FileListIndex(startIndex + i);
        m_pathToIndex[fileInfo.filePath] = FileListIndex(startIndex + i);
        emit fileAdded(FileListIndex(startIndex + i), fileInfo);
    }
    // 重建后续索引的映射
    rebuildMappings();
}
// === 内部辅助方法 ===
void FileInfoRepository::rebuildMappings()
{
    m_nameToIndex.clear();
    m_idToIndex.clear();
    m_pathToIndex.clear();
    for (int i = 0; i < m_files.size(); ++i) {
        const UnifiedFileInfo& info = m_files[i].info;
        m_nameToIndex[info.fileName] = FileListIndex(i);
        m_idToIndex[info.fileIdentity] = FileListIndex(i);
        m_pathToIndex[info.filePath] = FileListIndex(i);
    }
}
void FileInfoRepository::maintainIntegrity()
{
    // 移除无效条目
    for (int i = m_files.size() - 1; i >= 0; --i) {
        if (!m_files[i].info.isValid()) {
            m_files.removeAt(i);
        }
    }
    rebuildMappings();
}
void FileInfoRepository::logRepositoryState() const
{
    for (int i = 0; i < m_files.size(); ++i) {
        const UnifiedFileInfo& info = m_files[i].info;
    }
}
FileListIndex FileInfoRepository::findNextAvailableIndex() const
{
    return FileListIndex(m_files.size());
}
void FileInfoRepository::updateFileEntry(int listIndex, const UnifiedFileInfo& fileInfo)
{
    m_files[listIndex].info = fileInfo;
    // 更新映射
    const UnifiedFileInfo& info = m_files[listIndex].info;
    m_nameToIndex[info.fileName] = FileListIndex(listIndex);
    m_idToIndex[info.fileIdentity] = FileListIndex(listIndex);
    m_pathToIndex[info.filePath] = FileListIndex(listIndex);
}
void FileInfoRepository::emitFileUpdated(int listIndex)
{
    emit fileUpdated(FileListIndex(listIndex), m_files[listIndex].info);
}